#include<cstdio>
#include<cstring>
#include<iostream>
using std::cout;
using std::endl;
const int maxn=17;
long long dp[1<<16][maxn];
int x[maxn],y[maxn],n,m,map[6][6],h[6][6];
int min(int x,int y){return x<y?x:y;}
int max(int x,int y){return x>y?x:y;}
int abs(int x){return x>0?x:-x;}
bool judeg(int state,int a,int b)
{
	if(x[a]==x[b])
	{
		for(int i=min(y[a],y[b]);i<=max(y[a],y[b]);i++)
		{
			int kind=map[x[a]][i],loc=h[x[a]][i];
			if(kind==1)return false;
			if(kind==0&& (state & (1<<(loc-1)))==0)return false;
		}
		return true;
	}
	if(y[a]==y[b])
	{
		for(int i=min(x[a],x[b]);i<=max(x[a],x[b]);i++)
		{
			int kind=map[i][y[a]],loc=h[i][y[a]];
			if(kind==1)return false;
			if(kind==0&& (state & (1<<(loc-1)))==0)return false;
		}
		return true;
	}
	if(x[a]+y[a]==x[b]+y[b])
	{
		if(x[b]>x[a]){int t=b;b=a;a=t;}
		for(int i=0;i <=x[a]-x[b];i++)
		{
			int kind=map[x[b]+i][y[b]-i],loc=h[x[b]+i][y[b]-i];
			if(kind==1)return false;
			if(kind==0&& (state & (1<<(loc-1)))==0)return false;
		}
		return true;
	}
	if(x[a]-y[a]==x[b]-y[b])
	{
		if(x[b]>x[a]){int t=b;b=a;a=t;}
		for(int i=0;i <=x[a]-x[b];i++)
		{
			int kind=map[x[b]+i][y[b]+i],loc=h[x[b]+i][y[b]+i];
			if(kind==1)return false;
			if(kind==0&& (state & (1<<(loc-1)))==0)return false;
		}
		return true;
	}
	return true;
}
int main()
{
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		int t=0;
		for(int i=1;i<=n;i++)
			for(int j=1;j<=m;j++)
			{
				scanf("%d",&map[i][j]);
				if(map[i][j]==0)
				{
					t++;
					x[t]=i;y[t]=j;h[i][j]=t;
				}
			}
		memset(dp,0,sizeof(dp));
		for(int i=1;i<=t;i++)dp[1<<(i-1)][i]=1;
		int state=(1<<t)-1;
		for(int s=3;s<=state;s++)
			for(int i=1;i<=t;i++)
				if( s& 1<<(i-1) )
				{
					for(int j=1;j<=t;j++)
						if(i!=j&& s& 1<<(j-1) &&judeg(s,i,j))
							dp[s][i]+=dp[s-(1<<(i-1))][j];
				}
		long long ans=0;
		for(int i=1;i<=t;i++)ans+=dp[state][i];
		cout<<ans<<endl;
	}
	return 0;
}





